package com.mutouren.web.sso;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.mutouren.common.entity.ResultCode;
import com.mutouren.common.entity.ResultInfo;
import com.mutouren.common.entity.SignResultInfo;
import com.mutouren.common.session.SessionConfig;
import com.mutouren.common.session.SessionManager;
import com.mutouren.common.session.UserInfo;
import com.mutouren.common.utils.CookieUtils;
import com.mutouren.common.utils.DigestUtils;
import com.mutouren.common.utils.StringUtils;
import com.mutouren.modules.ca.model.User;
import com.mutouren.modules.ca.service.UserService;
import com.mutouren.modules.sso.model.Register;
import com.mutouren.modules.sso.service.RegisterService;
import com.mutouren.web.WebUtils;

@Controller
@RequestMapping(value="/sso")
public class SSOAction {
	
	@Resource
	private UserService userService;	
	
	@Resource
	private RegisterService registerService;	

	@RequestMapping(value="/login.action")
	public String login(String userName, String password,
			String appAlias, String redirect_uri, String state,
			HttpServletRequest request, HttpServletResponse response) throws IOException {
		
		// 检验协议
		if (!WebUtils.isPost(request)) {
			if (!check_login_protocol(appAlias, redirect_uri, state, response)) {
				return null;
			}
			
			// 直接重定向
			UserInfo userInfo = SessionManager.getSession().get(request);
			if (userInfo != null) {
				String ticket = TicketManager.createTicket(userInfo);
				String redirectUrl = String.format("%s?ticket=%s&state=%s", redirect_uri, ticket, state);
				return "redirect:" + redirectUrl;
			} else {
				request.setAttribute("redirect_uri", request.getParameter("redirect_uri"));
				request.setAttribute("state", request.getParameter("state"));		
				request.setAttribute("appAlias", request.getParameter("appAlias"));					
				return "frame/ssologin";	
			}		
		}
		
		// 检验登录
		request.setAttribute("actionName", WebUtils.getActionName(request));		
		List<String> errors = new ArrayList<String>();
		UserInfo userInfo = null;
		if(!this.validate(request, null, errors)) {
			ResultInfo<User> result = this.userService.login(userName, password);
			
			if (result.getCode() == ResultCode.SUCCESS.value) {
				userInfo = convertToUserInfo(result.getInfo());
				onLoginSuccessEvent(request, response, userInfo);
			} else {
				errors.add(result.getMessage());
			}
		}

		// 重定向
		if (errors.size() == 0) {	
			String ticket = TicketManager.createTicket(userInfo);
			String redirectUrl = String.format("%s?ticket=%s&state=%s", redirect_uri, ticket, state);
			return "redirect:" + redirectUrl;
		} else {
			request.setAttribute("errorMsg", WebUtils.getErrorMessage(errors));

			request.setAttribute("userName", request.getParameter("userName"));
			request.setAttribute("password", request.getParameter("password"));		
			request.setAttribute("redirect_uri", request.getParameter("redirect_uri"));
			request.setAttribute("state", request.getParameter("state"));		
			request.setAttribute("appAlias", request.getParameter("appAlias"));				
			return "frame/ssologin";
		}
	}
	
	@RequestMapping(value="/getUserInfo.action")
	@ResponseBody
	public SignResultInfo<UserInfo> getUserInfo(String appAlias, String ticket, 
		HttpServletResponse response) {		
		SignResultInfo<UserInfo> result = new SignResultInfo<UserInfo>();
		
		// 检验
		if (StringUtils.isBlank(appAlias) || StringUtils.isBlank(ticket)) {
			result.setCode(ResultCode.PARAMERROR.value);
			result.setMessage("参数为空");
			return result;
		}
		
		Register register = this.registerService.getByAppAlias(appAlias);
		if (register == null) {
			result.setCode(ResultCode.FAIL.value);
			result.setMessage("appAlias无效");
			return result;
		}
		
		// 获取userInfo
		UserInfo userInfo = TicketManager.getUserInfo(ticket);
		if (userInfo == null) {
			result.setCode(ResultCode.FAIL.value);
			result.setMessage("ticket无效");
			return result;
		}	
		
		// 结果
		result.setCode(ResultCode.SUCCESS.value);
		result.setInfo(userInfo);
		doSign(result, register.getAppSecret());
		
		return result;
	}
	
	private void doSign(SignResultInfo<UserInfo> result, String appSecret) {		
		result.setTimestamp(new Date().getTime());
		UserInfo userInfo = result.getInfo();
		
		String sourceSign = String.format("%s%s%s%s%s", 
				userInfo.getUserName(), 
				userInfo.getEmail() == null ? "" : userInfo.getEmail().trim(), 
				userInfo.getMobile() == null ? "" : userInfo.getMobile().trim(),
				result.getTimestamp(), appSecret);
		String sign = DigestUtils.MD5(sourceSign);
		result.setSign(sign);
	}
	
	private void onLoginSuccessEvent(HttpServletRequest request, HttpServletResponse response, UserInfo userInfo) {
		String sessionId = SessionManager.createSessionId();
		//ServletContext context = ContextLoader.getCurrentWebApplicationContext().getServletContext();
		//UserInfo userInfo = getUserInfo(person);
		userInfo.setLoginTime(new Date().getTime());
				
		// cookie
		CookieUtils.set(response, SessionConfig.cookieName, sessionId, request.getContextPath());
		
		// session
		SessionManager.getSession().set(request, sessionId, userInfo);
	}	
	
	private UserInfo convertToUserInfo(User user) {
		UserInfo result = new UserInfo();
		result.setUserId(Integer.parseInt(user.getUserId().toString()));
		result.setUserName(user.getUserName());
		result.setEmail(user.getEmail());
		result.setMobile(user.getMobile());
		
		return result;
	}
	
	private boolean check_login_protocol(String appAlias, String redirect_uri, String state, 
			HttpServletResponse response) throws IOException {
		String message = "";
		
		do {
			if (StringUtils.isBlank(appAlias)) {
				message = "appAlias为空";break;
			}
			if (StringUtils.isBlank(redirect_uri)) {
				message = "redirect_uri为空";break;
			}
			
			Register obj = this.registerService.getByAppAlias(appAlias);
			if (obj == null) {
				message = "appAlias无效";break;
			}
		} while(false);
		
		if (!StringUtils.isBlank(message)) {
			response.setContentType("text/plain;charset=utf-8");
			response.getWriter().write(message);
			return false;
		} else {
			return true;
		}
	}
	
	private boolean validate(HttpServletRequest request, Object model, List<String> errors ) {
		String actionName = (String) request.getAttribute("actionName");

		if (actionName.equals("login")) {	
			String userName = request.getParameter("userName");
			String password = request.getParameter("password");
			if (StringUtils.isBlank(userName) || StringUtils.isBlank(password)) {
				errors.add("登录名，密码不能为空");
			}			
		}

		return errors.size() > 0;
	}	
}










// 1.web应用重定向到sso服务
//redirect_uri
//appAlias(等同于client_id)
//state(透传参数)

// 2. web应用请求sso服务api，通过ticket获取user身份
//appAlias(等同于client_id)
//ticket
